﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// add
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using FormBaseLib;

namespace FormBase
{
    public partial class FPGM0070 : Form
    {
        //CProject mProject = Program.gProject;
        //DataSet mds1 = new DataSet("DataSetName");
        //DataTable mT1;
        //DataTable mT2;
//        DataSet mdsNew = new DataSet("DataSetNew");

        XMLKeyValueReading mX1 = new XMLKeyValueReading();
        delegate void ShowMsgEventHandler(string sMsg, Color color1);
        enumEntryMode mEntryMode;
        

        public FPGM0070()
        {
            InitializeComponent();
        }

        private void FPGM0070_Load(object sender, EventArgs e)
        {
            myEntryLoad();
        }

        private void btnClear_Click(object sender, EventArgs e)
        {

        }
        //private void myCreateDataSet()
        //{
        //    DataSet mds1 = new DataSet("DataSetName");
        //    DataTable mT1;
        //    DataTable mT2;

        //    // TABLE MASTER
        //    mT1 = new DataTable("T1"); 
        //    mT1.Columns.Add("FRecNo", typeof(long));
        //    mT1.Columns.Add("FS01", typeof(string));
        //    mT1.Columns.Add("FCName", typeof(string));  // ?? how to define the length ?
        //    mT1.Columns.Add("FI01", typeof(int));
        //    mT1.Columns.Add("FD01", typeof(decimal));
        //    mT1.Columns.Add("FCreateTime", typeof(DateTime));
        //    mT1.Columns.Add("FUpdateTime", typeof(DateTime));
        //    mT1.PrimaryKey = new DataColumn[] { mT1.Columns["FRecNo"]};
        //    mT1.Rows.Add(1, "PR", "中文測試1111", 1, 100.75, DateTime.Now, DateTime.Now);
        //    mT1.Rows.Add(2, "PR", "中文測試2222", 1, 200.85, DateTime.Now, DateTime.Now);

        //    // TABLE SALVE:
        //    // TABLE INVOICE DETAIL
        //    mT2 = new DataTable("T2");
        //    mT2.Columns.Add("FRecNo", typeof(long));
        //    mT2.Columns.Add("FSeqNo", typeof(int));
        //    mT2.Columns.Add("FItem", typeof(string));  // ?? how to define the length ?
        //    mT2.Columns.Add("FCName", typeof(string));  // ?? how to define the length ?
        //    mT2.Columns.Add("FD01", typeof(decimal));
        //    mT2.Columns.Add("FCreateTime", typeof(DateTime));
        //    mT2.Columns.Add("FUpdateTime", typeof(DateTime));
        //    mT2.PrimaryKey = new DataColumn[] { mT2.Columns["FRecNo"], mT2.Columns["FSeqNo"] };
        //    mT2.Rows.Add(1, 1, "ITEM 1", "中文測試1111", 100.0, DateTime.Now, DateTime.Now);
        //    mT2.Rows.Add(1, 2, "ITEM 2", "中文測試2222", 0.75, DateTime.Now, DateTime.Now);
        //    mT2.Rows.Add(2, 1, "ITEM 1", "中文測試3333", 75.0, DateTime.Now, DateTime.Now);
        //    mT2.Rows.Add(2, 2, "ITEM 2", "中文測試4444", 75.0, DateTime.Now, DateTime.Now);
        //    mT2.Rows.Add(2, 3, "ITEM 3", "中文測試5555", 50.85, DateTime.Now, DateTime.Now);

        //    // Create a DataSet and put both tables in it.
        //    mds1.Prefix = "p";
        //    mds1.Namespace = "n";
        //    mds1.Tables.Add(mT1);
        //    mds1.Tables.Add(mT2);
        //}
        //private void myAddRecordT1()
        //{
        //    int iNew = mT1.Rows.Count + 1;
        //    string s1 = "ROW" + iNew;

        //    mT1.Rows.Add(s1, iNew);
        //}

        private bool myIsXMLXSDReady()
        {
            if (string.IsNullOrEmpty(txtXSDFile.Text))
            {
                ShowMsgError("Please create XML/XSD file first!");
                return false;
            }
            return true;
        }

        private void myCreateXMLXSDFile()
        {

            string sFile;
            DataSet mds1 = new DataSet("DataSetName");
            DataTable t1, t2, t3, t4;

            myActionBegin();

            /////////////// Part 1 create by code.
            // TABLE MASTER
            t1 = new DataTable("T1");
            t1.Columns.Add("FRecNo", typeof(long));
            t1.Columns.Add("FS01", typeof(string));
            t1.Columns.Add("FCName", typeof(string));  // ?? how to define the length ?
            t1.Columns.Add("FI01", typeof(int));
            t1.Columns.Add("FD01", typeof(decimal));
            t1.Columns.Add("FCreateTime", typeof(DateTime));
            t1.Columns.Add("FUpdateTime", typeof(DateTime));
            t1.PrimaryKey = new DataColumn[] { t1.Columns["FRecNo"] };

            // TABLE SALVE/DETAIL
            t2 = new DataTable("T2");
            t2.Columns.Add("FRecNo", typeof(long));
            t2.Columns.Add("FSeqNo", typeof(int));
            t2.Columns.Add("FItem", typeof(string));  // ?? how to define the length ?
            t2.Columns.Add("FCName", typeof(string));  // ?? how to define the length ?
            t2.Columns.Add("FD01", typeof(decimal));
            t2.Columns.Add("FCreateTime", typeof(DateTime));
            t2.Columns.Add("FUpdateTime", typeof(DateTime));
            t2.PrimaryKey = new DataColumn[] { t2.Columns["FRecNo"], t2.Columns["FSeqNo"] };

            // Create a DataSet and put both tables in it.
            mds1.Prefix = "p";
            mds1.Namespace = "n";
            mds1.Tables.Add(t1);
            mds1.Tables.Add(t2);

            // Data
            t1.Rows.Add(1, "PR", "中文測試1111", 1, 100.75, DateTime.Now, DateTime.Now);
            t1.Rows.Add(2, "PR", "中文測試2222", 1, 200.85, DateTime.Now, DateTime.Now);
            t1.AcceptChanges();

            t2.Rows.Add(1, 1, "ITEM 1", "中文測試1111", 100.0, new DateTime(2013, 1, 1), DateTime.Now);
            t2.Rows.Add(1, 2, "ITEM 2", "中文測試2222", 0.75, new DateTime(2013, 2, 1), DateTime.Now);
            t2.Rows.Add(2, 1, "ITEM 1", "中文測試1111", 75.0, new DateTime(2013, 3, 1), DateTime.Now);
            t2.Rows.Add(2, 2, "ITEM 2", "中文測試2222", 75.0, new DateTime(2013, 4, 1), DateTime.Now);
            t2.Rows.Add(2, 3, "ITEM 2", "中文測試3333", 50.85, new DateTime(2013, 5, 1), DateTime.Now);
            t2.Rows.Add(3, 1, "ITEM 1", "中文測試1111", null, new DateTime(2013, 6, 1), DateTime.Now);
            t2.Rows.Add(3, 2, "ITEM 2", "中文測試2222", null, new DateTime(2013, 7, 1), DateTime.Now);
            t2.AcceptChanges();

            /////////////// Part 2 create by existing DataSet/DataTable.
            DataSetCommon dsC1 = new DataSetCommon();
            DataSetCommon.TKeyValueDataTable TKeyValue_From;
            DataSetCommon.TTypeKeyValueDataTable TTypeKeyValue_From;
            TKeyValue_From = dsC1.TKeyValue;
            TTypeKeyValue_From = dsC1.TTypeKeyValue;

            t3 = TKeyValue_From.Clone();
            t4 = TTypeKeyValue_From.Clone();
            t3.TableName = "T3";
            t4.TableName = "T4";
            mds1.Tables.Add(t3);
            mds1.Tables.Add(t4);

            DataSetCommon.TKeyValueRow r3;
            r3 = (DataSetCommon.TKeyValueRow)t3.NewRow();
            r3.FKey = "1";
            r3.FValue = "1";
            t3.Rows.Add(r3);

            r3 = (DataSetCommon.TKeyValueRow)t3.NewRow();
            r3.FKey = "2";
            r3.FValue = "2";
            t3.Rows.Add(r3);

            r3 = (DataSetCommon.TKeyValueRow)t3.NewRow();
            r3.FKey = "3";
            r3.FValue = "3";
            t3.Rows.Add(r3);
            r3.AcceptChanges();

            DataSetCommon.TTypeKeyValueRow r4;
            r4 = (DataSetCommon.TTypeKeyValueRow)t4.NewRow();
            r4.FType = "1";
            r4.FKey = "1";
            r4.FValue = "1";
            t4.Rows.Add(r4);

            r4 = (DataSetCommon.TTypeKeyValueRow)t4.NewRow();
            r4.FType = "2";
            r4.FKey = "2";
            r4.FValue = "2";
            t4.Rows.Add(r4);

            r4 = (DataSetCommon.TTypeKeyValueRow)t4.NewRow();
            r4.FType = "3";
            r4.FKey = "3";
            r4.FValue = "3";
            t4.Rows.Add(r4);
            r4.AcceptChanges();

            txtOutput.Text = mds1.GetXml();

            File.WriteAllText(@".\App_Data\Data0070.xml", mds1.GetXml());
            File.WriteAllText(@".\App_Data\Data0070-ASCII.xml", mds1.GetXml(), Encoding.ASCII);
            File.WriteAllText(@".\App_Data\Data0070-defaultAnsi.xml", mds1.GetXml(), Encoding.Default);
            //File.WriteAllText(@".\App_Data\Data0070-utf8.xml", mds1.GetXml(), Encoding.UTF8);
            File.WriteAllText(@".\App_Data\Data0070-unicode.xml", mds1.GetXml(), Encoding.Unicode);

            File.WriteAllText(@".\App_Data\Data0070.xsd", mds1.GetXmlSchema());
            File.WriteAllText(@".\App_Data\Data0070-defaultAnsi.xsd", mds1.GetXmlSchema(), Encoding.Default);
            //File.WriteAllText(@".\App_Data\Data0070-utf8.xsd", mds1.GetXmlSchema().Replace("utf-16", "utf-8"), Encoding.UTF8);
            File.WriteAllText(@".\App_Data\Data0070-unicode.xsd", mds1.GetXmlSchema(), Encoding.Unicode);

            // 確認使用此PATTERN:
            sFile = Path.GetFullPath(@".\App_Data\Data0070-utf8.xsd");
            File.WriteAllText(sFile, mds1.GetXmlSchema().Replace("utf-16", "utf-8"), Encoding.UTF8); // bug refer to MSDN
            txtXSDFile.Text = sFile;

            sFile = Path.GetFullPath(@".\App_Data\Data0070-utf8.xml");
            File.WriteAllText(sFile, mds1.GetXml(), Encoding.UTF8);
            txtXMLFile.Text = sFile;
        }



        private void CopySchemaColumnAndPK(DataTable tFrom, DataTable tTo)
        {
            tTo.Columns.Clear();
            foreach (DataColumn c1 in tFrom.Columns)
                tTo.Columns.Add(c1);

            //T2.PrimaryKey = new DataColumn[] { mT2.Columns["FRecNo"], mT2.Columns["FSeqNo"] };

            //foreach(DataColumn c1 in tFrom.PrimaryKey)
            //    tTo.PrimaryKey = 
        }
        private void myActionBegin()
        {
            ShowMsg(string.Empty);
        }
        private void myLoadAllRecords(string sTableName)
        {
            myActionBegin();

            if (!myIsXMLXSDReady()) return;

            DataSet dsAll = myReadXmlAll();
            if (dsAll.Tables.Contains(sTableName))
            {
                dataGridView1.AutoGenerateColumns = true;
                dataGridView1.DataSource = dsAll;
                //dataGridView1.DataMember = "T2";
                dataGridView1.DataMember = sTableName;
            }
            else
            {
                dataGridView1.DataSource = null;
                dataGridView1.DataMember = string.Empty;
                if (sTableName.Length>0)
                    ShowMsgError("Nothing to show for table name=" + sTableName);
            }
        }

        private void btnDefault_Click(object sender, EventArgs e)
        {
            myDefault();
        }
        private void myDefault()
        {
            txtFRecNo.Text = "K01";
            txtXMLFile.Text = "";
        }

        private void createXMLAndXSDFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            myCreateXMLXSDFile();
        }

        private void loadSchemaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //myLoadAllRecords();
        }
        private void OnShowMsg(string sMsg, Color color1)
        {
            lblStatus.Text = sMsg;
            if (lblStatus.ForeColor != color1)
                lblStatus.ForeColor = color1;
        }
        public void ShowMsg(string sMsg)
        {
            CProject.mApp.mAction.AppendMsgDebug(sMsg);
            Invoke(new ShowMsgEventHandler(OnShowMsg), new object[] { sMsg, SystemColors.ControlText });
        }
        public void ShowMsgError(string sMsg)
        {
            CProject.mApp.mAction.AppendMsgDebug(sMsg);
            Invoke(new ShowMsgEventHandler(OnShowMsg), new object[] { sMsg, Color.Red });
        }

        private void myEntryLoad()
        {
            Text = "XML Usage";

            dataGridView1.AllowUserToAddRows = false;
            dataGridView1.AllowUserToDeleteRows = false;
            dataGridView1.AllowUserToOrderColumns = true;
            dataGridView1.ReadOnly = true;
            dataGridView1.AutoGenerateColumns = true;

            rdoSortByPK.Checked = true;

            txtOutput.WordWrap = false;
            txtOutput.ScrollBars = ScrollBars.Both;

            mX1.LoadFile();

            myEntryModeAdd();

            lstLoadTable.Items.Add("0 None");
            lstLoadTable.Items.Add("1 T1");
            lstLoadTable.Items.Add("2 T2");
            lstLoadTable.Items.Add("3 T3");
            lstLoadTable.Items.Add("4 T4");

        }
        private void myEntryModeAdd()
        {
            mEntryMode = enumEntryMode.Add;
            txtEntryMode.Text = Enum.GetName(typeof(enumEntryMode), mEntryMode);

            btnEntryAdd.Enabled = true;
            btnEntryDelete.Enabled = false;
            btnEntryUpdate.Enabled = false;

            txtFRecNo.Enabled = true;
            txtFSeqNo.Enabled = true;
            txtFItem.Enabled = true;
            txtFCName.Enabled = true;
            txtFD01.Enabled = true;
            txtFCreateTime.Enabled = false;
            txtFUpdateTime.Enabled = false;
        }
        private void myEntryModeUpdate()
        {
            mEntryMode = enumEntryMode.Update;
            txtEntryMode.Text = Enum.GetName(typeof(enumEntryMode), mEntryMode);

            btnEntryAdd.Enabled = false;
            btnEntryDelete.Enabled = true;
            btnEntryUpdate.Enabled = true;

            txtFRecNo.Enabled = false;
            txtFSeqNo.Enabled = false;
            txtFItem.Enabled = true;
            txtFCName.Enabled = true;
            txtFD01.Enabled = true;
            txtFCreateTime.Enabled = false;
            txtFUpdateTime.Enabled = false;
        }
        private void myEntryModeView()
        {
            mEntryMode = enumEntryMode.View;
            txtEntryMode.Text = Enum.GetName(typeof(enumEntryMode), mEntryMode);

            btnEntryAdd.Enabled = false;
            btnEntryDelete.Enabled = false;
            btnEntryUpdate.Enabled = false;

            // don't care.
            //txtFRecNo.Enabled = false;
            //txtFSeqNo.Enabled = false;
            //txtFItem.Enabled = true;
            //txtFCName.Enabled = true;
            //txtFD01.Enabled = true;
            //txtFCreateTime.Enabled = false;
            //txtFUpdateTime.Enabled = false;
        }
        private void myEntryQueryKey() 
        {
            int iFRecNo, iFSeqNo;

            myActionBegin();

            if (!myEntryVerifyKey())
                return;

            // get values from entry.
            if (!Int32.TryParse(txtFRecNo.Text, out iFRecNo))
            {
                ShowMsgError("Error Rec No.");
                return;
            }
            if (!Int32.TryParse(txtFSeqNo.Text, out iFSeqNo))
            {
                ShowMsgError("Error Seq No.");
                return;
            }

            DataSet dsAll = myReadXmlAll();
            DataTable T2 = dsAll.Tables["T2"];
            string sRowFilter = string.Format("FRecNo = {0} AND FSeqNo = {1}", iFRecNo, iFSeqNo);
            DataRow[] rowsMatch = T2.Select(sRowFilter);
            if (rowsMatch.Length<1)
            {
                ShowMsgError("Data not found. " + sRowFilter);
                return;
            }
            txtFItem.Text = rowsMatch[0]["FItem"].ToString();
            txtFCName.Text = rowsMatch[0]["FCName"].ToString();
            txtFD01.Text = rowsMatch[0]["FD01"].ToString();
            txtFCreateTime.Text = rowsMatch[0]["FCreateTime"].ToString();
            txtFUpdateTime.Text = rowsMatch[0]["FUpdateTime"].ToString();
            ShowMsg("OK");
        }
        private bool myEntryVerifyKey()
        {
            int i1;
            bool bOK;

            if (!myIsXMLXSDReady()) return false;            

            // check keys empty ?
            if (string.IsNullOrEmpty(txtFRecNo.Text))
            {
                ShowMsgError("Please input Rec No.");
                return false;
            }
            if (string.IsNullOrEmpty(txtFSeqNo.Text))
            {
                ShowMsgError("Please Input Seq No.");
                return false;
            }

            // check keys valid ?
            bOK = false;
            if (Int32.TryParse(txtFRecNo.Text, out i1))
                if ((i1 > 0) || (i1 < 1001))
                    bOK = true;
            if (!bOK)
            {
                ShowMsgError("Please input Rec No. in 1 to 1000.");
                return false;
            }

            bOK = false;
            if (Int32.TryParse(txtFSeqNo.Text, out i1))
                if ((i1 > 0) || (i1 < 501))
                    bOK = true;
            if (!bOK)
            {
                ShowMsgError("Please input Rec No. in 1 to 500.");
                return false;
            }

            return true;
        }

        private void btnEntryQueryKey_Click(object sender, EventArgs e)
        {
            myEntryQueryKey();
        }

        private void btnLoadAll_Click(object sender, EventArgs e)
        {
            //myLoadAllRecords();
        }

        private void mySampleSearch()
        {
            txtQFCName.Text = "中文測試2*";
            txtQFCreateTimeB.Text = "2013/2/1";
            txtQFCreateTimeE.Text = "2013/5/1";
        }
        private void btnSampleSearch_Click(object sender, EventArgs e)
        {
            mySampleSearch(); 
        }

        private DataSet myReadXmlAll()
        {
            DataSet dsAll = new DataSet("dsAll");
            dsAll.Clear();
            // 確認使用此PATTERN:
            //mdsNew.ReadXmlSchema(@".\App_Data\Data0070-utf8.xsd");  // utf-8
            //mdsNew.ReadXml(@".\App_Data\Data0070-utf8.xml", XmlReadMode.ReadSchema);  // utf-8
            dsAll.ReadXmlSchema(txtXSDFile.Text);  // utf-8
            dsAll.ReadXml(txtXMLFile.Text, XmlReadMode.ReadSchema);  // utf-8
            dsAll.Locale = System.Globalization.CultureInfo.CurrentUICulture;
            return dsAll;
        }
        private bool myQuerySearch()
        {
            int iFRecNo, iFSeqNo;
            string sFCreateTimeB;
            string sFCreateTimeE;
            string sFCName, sFItem;
            bool bIsNullFD01;

            StringBuilder sb1 = new StringBuilder();
            myActionBegin();

            if (!myIsXMLXSDReady()) 
                return false;

            DataSet dsAll = myReadXmlAll();
            DataTable T2 = dsAll.Tables["T2"];
            
            // get values from Query form.
            // refer to http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression(v=vs.90).aspx
            sb1.Length = 0;
            if (Int32.TryParse(txtQFRecNo.Text, out iFRecNo))
                if (iFRecNo != 0)
                    sb1.AppendFormat(" AND FRecNo={0}", iFRecNo);

            if (Int32.TryParse(txtQFSeqNo.Text, out iFSeqNo))
                if (iFSeqNo != 0)
                    sb1.AppendFormat(" AND FSeqNo={0}", iFSeqNo);

            sFItem = txtQFItem.Text.TrimEnd();
            if (sFItem.Length > 0)
                sb1.AppendFormat(" AND FItem='{0}'", sFItem);

            sFCName = txtQFCName.Text.TrimEnd();
            if (sFCName.Length > 0)
                sb1.AppendFormat(" AND FCName LIKE '{0}'", sFCName);

            sFCreateTimeB = txtQFCreateTimeB.Text.TrimEnd();
            if (sFCreateTimeB.Length > 0)
                sb1.AppendFormat(" AND FCreateTime>=#{0}#", sFCreateTimeB);

            sFCreateTimeE = txtQFCreateTimeE.Text.TrimEnd();
            if (sFCreateTimeE.Length > 0)
                sb1.AppendFormat(" AND FCreateTime<#{0}#", sFCreateTimeE);

            // todo is null: '"Isnull(Col1,'Null Column') = 'Null Column'"
            if (chkIsNullFD01.Checked)
                sb1.AppendFormat(" AND Isnull(FD01,'Null Column') = 'Null Column'");

            if (sb1.Length > 0)
                sb1.Remove(0, 5);
            //string sRowFilter = string.Format("FRecNo = {0}", iFRecNo);
            string sRowFilter = sb1.ToString();

            string sSortBy = string.Empty;
            if (rdoSortByCreateTime.Checked)
                sSortBy = "FCreateTime DESC";
            else
                sSortBy = string.Empty;


            txtOutput.Text = sb1.ToString();

            DataView dv1 = new DataView(T2, sRowFilter, sSortBy, DataViewRowState.CurrentRows);
            if (dv1.Count < 1)
            {
                dataGridView1.DataSource = null;
                dataGridView1.DataMember = string.Empty;
                ShowMsgError("Data not found in filter. " + sRowFilter);
                return true;
            }

            //DataRow[] rowsMatch = T2.Select(sRowFilter, sSortBy, DataViewRowState.CurrentRows);
            //if (rowsMatch.Length < 1)
            //{
            //    dataGridView1.DataSource = null;
            //    dataGridView1.DataMember = string.Empty;
            //    ShowMsgError("Data not found. " + sRowFilter);
            //    return false;
            //}
            //DataSet dsNew = new DataSet("dsNew");
            //dsNew.Tables.Add(dsAll.GetXmlSchema());


            //dataGridView1.AutoGenerateColumns = true;
            dataGridView1.DataSource = dv1;
            ShowMsg("OK");
            return true;
        }

        private void btnQuerySearch_Click(object sender, EventArgs e)
        {
            myQuerySearch();

        }

        private void lstLoadTable_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox lst1 = sender as ListBox;

            switch (lst1.SelectedIndex)
            {
                case 0:
                    myLoadAllRecords(string.Empty);
                    break;
                case 1:
                    myLoadAllRecords("T1");
                    break;
                case 2:
                    myLoadAllRecords("T2");
                    break;
                case 3:
                    myLoadAllRecords("T3");
                    break;
                case 4:
                    myLoadAllRecords("T4");
                    break;
            }
        }

        private void btnEntryRefreshBrowse_Click(object sender, EventArgs e)
        {

        }

        private void rdoSortByPK_CheckedChanged(object sender, EventArgs e)
        {

        }

    }
}
